package com.whmskj.xjlhsc.service;

import com.whmskj.xjlhsc.controller.vo.MonthlyEnergyConsumptionVO;
import com.whmskj.xjlhsc.controller.vo.ProcessYieldEnergyVO;
import com.whmskj.xjlhsc.entity.AttendanceStat;
import com.whmskj.xjlhsc.mapper.AttendanceMapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AttendanceService {
    private static final Logger logger = LoggerFactory.getLogger(AttendanceService.class);

    @Autowired
    private AttendanceMapper attendanceMapper;

    public List<AttendanceStat> getAttendanceStats() {
        // 获取数据库中的实际统计数据
        List<AttendanceStat> dbStats = attendanceMapper.statByWorkshopAndState();

        // 定义所有车间和出勤状态（新增"离职"状态）
        String[] workshops = {"前纺", "细纱", "络筒"};
        String[] states = {"出勤", "缺勤", "休息", "离职"};

        // 将数据库结果转换为Map，方便查找
        Map<String, Map<String, Integer>> statsMap = dbStats.stream()
                .collect(Collectors.groupingBy(
                        AttendanceStat::getPositions,
                        Collectors.toMap(
                                AttendanceStat::getStateOfAttendance,
                                AttendanceStat::getCount
                        )
                ));

        // 构建完整的结果列表
        List<AttendanceStat> result = new ArrayList<>();
        for (String workshop : workshops) {
            for (String state : states) {
                AttendanceStat stat = new AttendanceStat();
                stat.setPositions(workshop);
                stat.setStateOfAttendance(state);

                // 从数据库结果中获取计数，如果没有则设为0
                Integer count = statsMap.getOrDefault(workshop, new HashMap<>()).getOrDefault(state, 0);
                stat.setCount(count);

                result.add(stat);
            }
        }

        return result;
    }


    // 近7日工序产量/能耗
    public List<Map<String, Object>> getLast7DaysYieldEnergy(String process) {
        String end = java.time.LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).toString();
        String begin = java.time.LocalDateTime.now().minusDays(6).withHour(0).withMinute(0).withSecond(0).toString();

        List<Map<String, Object>> yieldList = attendanceMapper.sumYieldByDay(process, begin, end);
        List<Map<String, Object>> energyList = attendanceMapper.sumEnergyByDay(process, begin, end);

        // 组装7天（补0）
        java.time.format.DateTimeFormatter fmt = java.time.format.DateTimeFormatter.ofPattern("MM-dd");
        List<Map<String, Object>> result = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            String d = java.time.LocalDate.now().minusDays(6 - i).format(fmt);
            double yield = yieldList.stream().filter(m -> d.equals(String.valueOf(m.get("date")))).mapToDouble(m -> toDouble(m.get("value"))).findFirst().orElse(0.0);
            double energy = energyList.stream().filter(m -> d.equals(String.valueOf(m.get("date")))).mapToDouble(m -> toDouble(m.get("value"))).findFirst().orElse(0.0);
            Map<String, Object> row = new HashMap<>();
            row.put("date", d);
            row.put("yield", round2(yield));
            row.put("energyConsumption", round2(energy));
            row.put("process", process);
            result.add(row);
        }
        return result;
    }

    public List<Map<String, Object>> getAcTrend(LocalDate hour, String workshop) {
        return attendanceMapper.acTrendByWorkshop(hour, workshop);
    }

    /**
     * 空调温湿度趋势数据
     * @param workshop
     * @param hours
     * @return
     *//*
    public List<Map<String, Object>> getAcTrend(String workshop, Integer hours) {
        if (hours == null || hours <= 0 || hours > 48) {
            hours = 8;
        }
        java.time.LocalDateTime endDt = java.time.LocalDateTime.now().withMinute(59).withSecond(59).withNano(0);
        java.time.LocalDateTime beginDt = endDt.minusHours(hours - 1).withMinute(0).withSecond(0);
        String begin = beginDt.toString();
        String end = endDt.toString();

        List<Map<String, Object>> rows = attendanceMapper.acTrendByWorkshop(workshop, begin, end);


        // 然后在方法中使用日志而不是System.out
        logger.info("查询结果行数: {}", rows.size());
        for (int i = 0; i < rows.size(); i++) {
            logger.info("第{}行数据: {}", i+1, rows.get(i));
        }

        java.util.Map<String, Map<String, Object>> byHour = new java.util.HashMap<>();
        for (Map<String, Object> r : rows) {
            byHour.put(String.valueOf(r.get("ts_hour")), r);
        }

        // 创建日期时间格式化器，用于格式化小时粒度的时间
        java.time.format.DateTimeFormatter fmt = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00");
        List<Map<String, Object>> result = new ArrayList<>();
        // 遍历每个小时间隔，构建完整的小时序列数据
        for (int i = 0; i < hours; i++) {
            // 生成当前小时的时间键
            String key = beginDt.plusHours(i).format(fmt);
            // 从查询结果中获取该小时的数据
            Map<String, Object> r = byHour.get(key);
            // 构建返回结果的行数据
            Map<String, Object> row = new HashMap<>();
            // 提取时间字段（只保留小时分钟）
            row.put("time", key.substring(11, 16));
            // 仅在有数据时设置温度和湿度值
            if (r != null) {
                if (r.get("temperature") != null) {
                    row.put("temperature", round2(toDouble(r.get("temperature"))));
                }
                if (r.get("humidity") != null) {
                    row.put("humidity", round2(toDouble(r.get("humidity"))));
                }
            }
            // 设置车间名称
            row.put("workshop", workshop);
            result.add(row);
        }
        return result;
    }*/


    private double toDouble(Object v) {
        if (v == null) return 0.0;
        try { return Double.parseDouble(String.valueOf(v)); } catch (Exception e) { return 0.0; }
    }
    private double round2(double v) {
        return new java.math.BigDecimal(v).setScale(2, java.math.RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 获取机台运行状态统计数据
     */
    public Map<String, Integer> getMachineRunningStats(String workshop, List<String> processes) {
        List<Map<String, Object>> dbCounts = attendanceMapper.getMachineStatusCounts(workshop, processes);

        Map<String, Integer> result = new HashMap<>();
        // 初始化所有预期的状态，确保即使数据库中没有数据也返回0
        result.put("运行", 0);
        result.put("临停", 0);
        result.put("维保中", 0);
        result.put("离线", 0);

        // 填充数据库中实际存在的计数
        for (Map<String, Object> row : dbCounts) {
            String status = (String) row.get("status");
            Number count = (Number) row.get("count");
            if (status != null && result.containsKey(status)) {
                result.put(status, count.intValue());
            }
        }
        return result;
    }

    /**
     * 获取指定月份各工序机台的日能耗和月总能耗
     */
    public List<MonthlyEnergyConsumptionVO> getMonthlyEnergyConsumption(String process, LocalDate date) {
        if (date == null) {
            date = LocalDate.now();
        }
        // 格式化日期为Mapper所需的字符串格式
        String currentDateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        List<Map<String, Object>> rawData = attendanceMapper.getMonthlyMachineEnergy(process, currentDateStr);

        List<MonthlyEnergyConsumptionVO> result = new ArrayList<>();
        for (Map<String, Object> row : rawData) {
            MonthlyEnergyConsumptionVO vo = new MonthlyEnergyConsumptionVO();
            vo.setProcess((String) row.get("process"));
            vo.setMachine((String) row.get("machine"));
            // 确保从Map中获取的数值类型正确转换为BigDecimal
            vo.setDailyEnergyConsumption(row.get("dailyEnergyConsumption") != null ?
                    new BigDecimal(row.get("dailyEnergyConsumption").toString()) : BigDecimal.ZERO);
            vo.setMonthlyTotalEnergyConsumption(row.get("monthlyTotalEnergyConsumption") != null ?
                    new BigDecimal(row.get("monthlyTotalEnergyConsumption").toString()) : BigDecimal.ZERO);
            result.add(vo);
        }
        return result;
    }

}